﻿package vsg.engine {

	import flash.external.ExternalInterface;
	import flash.utils.*;
	import vsg.util.Runnable;
	import vsg.util.Thread;

	
	/**
	 * construct the Http Request Defined 
	 */
	public class Engine {

		private static const UNINIT:uint = 0;
		
		private static const INIT:uint = 1; 
		
		// build tmp array list 
		private var tmpClass:Array = [];
		
		private var classStateCache:Object = {};
		
		/**
		 * defeind temp load class state
		 */
		private var stateMap:Object = {};
		
		public function Engine() {

		}
		
		/**
		 * add the import class to object
		 */
		public function importClassName(className:String) {
			if (tmpClass.indexOf(className) == -1) {
				tmpClass.push(className);
				classStateCache[className] = UNINIT;
			}
		}
		

		public function run():void {
			
			var allInterrupt:Boolean = false;
			
			// --- check the object load init status ---
			var tm:uint = setInterval(function () {
				var isComplete:Boolean = true;
				
				for (var index in classStateCache) {
					
					if (classStateCache[index] == UNINIT) {
						isComplete = false;
						break;
					}
					
				}
				
				// --- check the isComplete and invoke javascript handle ---
				if (isComplete) {
					// fill the code
					callJsResult();
					
					// --- interrupt thread ---
					allInterrupt = true;
				}
				
				if (allInterrupt) {
					clearInterval(tm);
				}
		
			},20);
			
			
			// --- check the class status ---
			var tm2:uint = setInterval(function () {
				// --- get the temp class object ---				   
				for (var index = 0 ; index < tmpClass.length ; index++) {
					var className = tmpClass[index];
					
					/**
			 	 	* get thd Class state Object by ClassName from Object Cache
			 	 	*/				
					if (stateMap[ className ] == undefined) {
						stateMap[ className ] = new ClassObjectState(className);
						// --- add event ---
						
						try {
							var thread:Thread = new Thread( stateMap[ className ] );
							thread.start();
							
						} catch (err:Error) {
							trace("build thread error : " + err);
						}
					
					}					
				}

				if (allInterrupt) {
					clearInterval(tm2);
				}				
				
			},21);
			
			
			// --- check the class status ---
			var tm3:uint = setInterval(function () {
	   
				for (var index in stateMap) {
					
					var clsObjState:ClassObjectState = stateMap[ index ];
					if ( clsObjState.getState() == ClassObjectState.LOADED ) {
						
						// --- get find the dependent ---
						var dependentClass:Array = clsObjState.getDependentClasses();
						
						if (dependentClass.length > 0) {
							var isOK:Boolean = true;
							
							for (var depindex = 0 ; depindex < dependentClass.length ; depindex++) {
								
								var clsName = dependentClass[depindex];
								if (tmpClass.indexOf( clsName ) == -1) {
									// --- add the temp cache ---
									importClassName(clsName);
									
									isOK = false;
								}
								
								else {
									
									if (classStateCache[clsName] == UNINIT) {
										isOK = false;
										break;
									}
									
								}
							}
							
							if (isOK) {
								
								if (classStateCache[index] == UNINIT ) {
									executeClsObjectState( clsObjState );
								}
								// --- execute code ---
							}
						
						} else {
							
							if (classStateCache[index] == UNINIT ) {
								// ---- execute code ---
								
								executeClsObjectState( clsObjState );  
							}
						}
					
						
					}
				}

				if (allInterrupt) {
					clearInterval(tm2);
				}					
				
			},23);			
		}
		
		// --- call javascript function from javascrpt method ---
		private function callJsResult():void {
			
			try {
				
				ExternalInterface.call("VsEngineCom.flash_reponseHandle",1);
				
			} catch (err:Error) {
				trace("run error : " + err);
			}
			
		}
		
		
		private  function executeClsObjectState(objState:ClassObjectState):void {
			
			var jsSource:String = objState.getClassSource();
			var jsCode:String = objState.getClassName();
			
			try {

				//ExternalInterface.call("VsEngineCom.flash_debug","source : " + jsSource);
				
				
				ScriptLoaderGlobalHandle.execScriptCode( jsSource );
				classStateCache[jsCode] = INIT;
				
			} catch(err:Error) {
				ExternalInterface.call("VsEngineCom.flash_debug","err : " + err);
				
				trace(err);
			}
			
			
			
		}
		

	}
	
}